// This is the main DLL file.

#include "stdafx.h"

#include "PotatoSoft.ImageProcessing.h"


namespace PotatoSoft
{
	namespace ImageProcessing 
	{
		void ImageProcessing::cvHist_8u(
			array<byte> ^arrays,   
			array<byte> ^ % hist, 
			float rangeLow,
			float rangeHigh,
			int hbins,
			int width,
			int height,
			int wdStep,
			array<byte> ^mask
			)
		{
			pin_ptr<byte> d = &arrays[0];
			cv::Mat mat(height,width,CV_8UC1,(uchar*)d,(size_t)wdStep);
			int histSize[]={hbins};
			const float hranges[]={rangeLow,rangeHigh};
			const float* ranges[]={hranges};
			const int channels[]={0};
			cv::MatND matHist;
			cv::calcHist(&mat,1,channels,cv::Mat(),matHist,1,histSize,ranges);
			for (int i=0;i<hbins;i++)
				hist[i]=matHist.data[i];
			mat.release();
			matHist.release();
		}
		
		void ImageProcessing::cvLoad_8u(String ^fname,array<byte> ^%data, int % width, int % height, int % wdStep)
		{
			IplImage *image=0;
			image=cvLoadImage( (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(
				fname).ToPointer());
			width=image->width;
			height=image->height;
			IplImage *image2=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
			cvCvtColor(image,image2,CV_RGB2GRAY);
			wdStep=image2->widthStep;
			data = gcnew cli::array<byte>(width*height);
			for(int j=0; j<width*height; j++)
				data[j]=image2->imageData[j];
			cvReleaseImage(&image);
			cvReleaseImage(&image2);
		}

		void ImageProcessing::cvSave_8u(String ^fname,array<byte> ^data,int width, int height, int wdStep)
		{
			IplImage *image=0;
			image=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
			pin_ptr<byte> d = &data[0];
			cvSetData(image,(uchar*)d,width);
			cvSaveImage( (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(
				fname).ToPointer(),image);
		}

		float ImageProcessing::cvMean_8u(array<byte> ^data,int width, int height, int wdStep)
		{
			CvMat *mat = cvCreateMat(height,width,CV_8UC1);
			pin_ptr<byte> d = &data[0];
			cvSetData(mat,(uchar*)d,wdStep);
			float mean = (float)cv::mean(mat).val[0]; 
			cvReleaseMat(&mat);
			return (float)mean;
		}

		float ImageProcessing::cvStdDev_8u(array<byte> ^data,int width, int height, int wdStep)
		{
			CvMat *mat = cvCreateMat(height,width,CV_8UC1);
			pin_ptr<byte> d = &data[0];
			cvSetData(mat,(uchar*)d,wdStep);
			cv::Scalar mean;
			cv::Scalar stddev;
			meanStdDev(mat,mean,stddev);
			cvReleaseMat(&mat);
			return (float)stddev.val[0];
		}
	}
}